#include "LayerManager.h"

void * __cdecl

calloc(size_t num, register size_t size)
{
    register void *p;

    size *= num;
    if ((p = malloc(size)))
        memset(p, 0,size);
    return(p);
}

inline Pixel Reflect(Pixel pixel, unsigned char level)
{
    Pixel result;
    result.r = (pixel.r*level)>>8;
    result.g = (pixel.g*level)>>8;
    result.b = (pixel.b*level)>>8;
    result.a = pixel.a;
    return result;
}

inline unsigned char AlphaBlend8(unsigned char src, unsigned char dst, unsigned char alpha)
{
    return ((alpha * (src - dst))>>8) + dst;
}

LayerManager::LayerManager(int width, int height):
    m_nNumberOfLayers(0),
    m_pTopLayer(0),
    m_pBottomLayer(0),
    m_pAvailableSlot(0),
    m_nBackgroundColor(0),
    m_bTransparent(1)
{
    for (int i=0;i<MaxNumLayer;i++) {
        m_pLayer[i] = 0;
        m_pLayerFlag[i] = 0;
    }

    m_nViewPlaneWidth = width;
    m_nViewPlaneHeight = height;

    m_stViewRectPosition.x = 0;
    m_stViewRectPosition.y = 0;
}

LayerManager::~LayerManager()
{
    int i=0;
    while (m_nNumberOfLayers > 0 && i < MaxNumLayer)
    {
        if (m_pLayer[i]) {
            LayerRestore(i);
            if (m_pLayerFlag[i]) {
                if (m_pLayer[i]->SrcImage.address)
                    free((void*)m_pLayer[i]->SrcImage.address);
                m_pLayerFlag[i] = 0;
            }

            delete  m_pLayer[i];
            m_pLayer[i] = 0;
            m_nNumberOfLayers--;
        }
        i++;
    }

//    if (m_stTempBuffer.address)
//        free(m_stTempBuffer.address);

}

void LayerManager::RemoveAllLayers()
{
    int i=0;
    while (m_nNumberOfLayers > 0 && i < MaxNumLayer)
    {
        if (m_pLayer[i]) {
            LayerRestore(i);
            if (m_pLayerFlag[i]) {
                if (m_pLayer[i]->SrcImage.address)
                    free((void*)m_pLayer[i]->SrcImage.address);
                m_pLayerFlag[i] = 0;
            }

            delete  m_pLayer[i];
            m_pLayer[i] = 0;
            m_nNumberOfLayers--;
        }
        i++;
    }
    m_pTopLayer = 0;
    m_pBottomLayer = 0;
    m_pAvailableSlot = 0;
}

int LayerManager::DuplicateLayer(int index, int xin, int yin, int level, int style)
{
    unsigned int type = m_pLayer[index]->SrcImage.pixelFormat & 3;
    int temp = -1;
    int i=0, width, height, x, y, a;
    unsigned char * pSrc, * pDst;
    width = m_pLayer[index]->SrcImage.width;
    height = m_pLayer[index]->SrcImage.height;
    pSrc = (unsigned char *)m_pLayer[index]->SrcImage.address;
    BitmapBufInfo img;

    switch (type) {
        case 2 :
        case 3 :
            temp = m_pAvailableSlot;
            if ((m_nNumberOfLayers + 1) >= MaxNumLayer ) return -1;
            m_pLayer[m_pAvailableSlot] = new Layer;
            if (!m_pLayer[m_pAvailableSlot]) return -1;
            if (!m_pBottomLayer) m_pBottomLayer = m_pLayer[m_pAvailableSlot];

            img.width = width;
            img.height = height;
            pDst = (unsigned char*)calloc(width * height, 4);
            img.address = (Address)pDst;
            img.pitch = width * 4;
            img.pixelFormat = m_pLayer[index]->SrcImage.pixelFormat;

            m_pLayerFlag[m_pAvailableSlot] = 1;
            m_pLayer[m_pAvailableSlot]->Image = img;
            m_pLayer[m_pAvailableSlot]->SrcImage = img;
            m_pLayer[m_pAvailableSlot]->Position.x = xin;
            m_pLayer[m_pAvailableSlot]->Position.y = yin;
            m_pLayer[m_pAvailableSlot]->Transparency = level;
            m_pLayer[m_pAvailableSlot]->Index = m_pAvailableSlot;
            m_pLayer[m_pAvailableSlot]->pPrevLayer = m_pTopLayer;
            m_pLayer[m_pAvailableSlot]->pNextLayer = 0;
            m_pLayer[m_pAvailableSlot]->Visible = true;
            m_pLayer[m_pAvailableSlot]->StretchInfo.Width = img.width;
            m_pLayer[m_pAvailableSlot]->StretchInfo.Height = img.height;
            m_pLayer[m_pAvailableSlot]->StretchInfo.OffsetX = 0;
            m_pLayer[m_pAvailableSlot]->StretchInfo.OffsetY = 0;
            m_pLayer[m_pAvailableSlot]->bZoom = false;
            m_pLayer[m_pAvailableSlot]->bTransform = false;
            m_pLayer[m_pAvailableSlot]->uRenderMethod = 0;

            switch (style) {
                case 0:
                    for (i=0; i<width*height; i++) {
                        ((int*)pDst)[i] = ((int*)pSrc)[i];
                    }
                    break;
                case 1:
                    for (y=0; y<height; y++) {
                        for (x=0; x<width; x++) {
                            ((int*)pDst)[x] = ((int*)pSrc)[width - 1 - x];
                        }
                        pDst += img.pitch;
                        pSrc += img.pitch;
                    }
                    break;
                case 2:
                    pSrc += img.pitch *( height-1);
                    for (y=0; y<height; y++) {
                        for (x=0; x<width; x++) {
                            ((int*)pDst)[x] = ((int*)pSrc)[x];
                        }
                        pDst += img.pitch;
                        pSrc -= img.pitch;
                    }
                    break;
                case 3:

                    for (y=0; y<height; y++) {
                        a=165;
                        for (x=0; x<width; x++) {
                            i++;
                            if (a > 60) a= a - 2;
                            else a -= 1;
                            if (a<=0) a=0;
                            ((Pixel*)pDst)[width - 1 - x] = Reflect(((Pixel*)pSrc)[x],a);
                        }
                        pDst += img.pitch;
                        pSrc += img.pitch;
                    }
                    break;
            }

            if (m_pTopLayer) m_pTopLayer->pNextLayer = m_pLayer[m_pAvailableSlot];
            m_pTopLayer = m_pLayer[m_pAvailableSlot];
            while (m_pLayer[m_pAvailableSlot] != 0) m_pAvailableSlot++;
            m_nNumberOfLayers++;
            break;
         case 1 :
            temp = m_pAvailableSlot;
            if ((m_nNumberOfLayers + 1) >= MaxNumLayer ) return -1;
            m_pLayer[m_pAvailableSlot] = new Layer;
            if (!m_pLayer[m_pAvailableSlot]) return -1;
            if (!m_pBottomLayer) m_pBottomLayer = m_pLayer[m_pAvailableSlot];

            img.width = width;
            img.height = height;
            pDst = (unsigned char*)calloc(width * height, 1);
            img.address = (Address)pDst;
            img.pitch = width * 1;
            img.pixelFormat = m_pLayer[index]->SrcImage.pixelFormat;

            m_pLayerFlag[m_pAvailableSlot] = 1;
            m_pLayer[m_pAvailableSlot]->Image = img;
            m_pLayer[m_pAvailableSlot]->SrcImage = img;
            m_pLayer[m_pAvailableSlot]->Position.x = xin;
            m_pLayer[m_pAvailableSlot]->Position.y = yin;
            m_pLayer[m_pAvailableSlot]->Transparency = level;
            m_pLayer[m_pAvailableSlot]->Index = m_pAvailableSlot;
            m_pLayer[m_pAvailableSlot]->pPrevLayer = m_pTopLayer;
            m_pLayer[m_pAvailableSlot]->pNextLayer = 0;
            m_pLayer[m_pAvailableSlot]->Visible = true;
            m_pLayer[m_pAvailableSlot]->StretchInfo.Width = img.width;
            m_pLayer[m_pAvailableSlot]->StretchInfo.Height = img.height;
            m_pLayer[m_pAvailableSlot]->StretchInfo.OffsetX = 0;
            m_pLayer[m_pAvailableSlot]->StretchInfo.OffsetY = 0;
            m_pLayer[m_pAvailableSlot]->bZoom = false;
            m_pLayer[m_pAvailableSlot]->bTransform = false;
            m_pLayer[m_pAvailableSlot]->uRenderMethod = 0;


            switch (style) {
                case 0:
                    for (i=0; i<width*height; i++) {
                        pDst[i] = pSrc[i];
                    }
                    break;
                case 1:
                    for (y=0; y<height; y++) {
                        for (x=0; x<width; x++) {
                            pDst[x] = pSrc[width - 1 - x];
                        }
                        pDst += img.pitch;
                        pSrc += img.pitch;
                    }
                    break;
                case 2:
                    pSrc += img.pitch *( height-1);
                    for (y=0; y<height; y++) {
                        for (x=0; x<width; x++) {
                            pDst[x] = pSrc[x];
                        }
                        pDst += img.pitch;
                        pSrc -= img.pitch;
                    }
                    break;
            }

            if (m_pTopLayer) m_pTopLayer->pNextLayer = m_pLayer[m_pAvailableSlot];
            m_pTopLayer = m_pLayer[m_pAvailableSlot];
            while (m_pLayer[m_pAvailableSlot] != 0) m_pAvailableSlot++;
            m_nNumberOfLayers++;
            break;
    }

    return temp;
}

int LayerManager::AddLayer(BitmapBufInfo & img, int x, int y, int level)
{
    int temp = m_pAvailableSlot;
    if ((m_nNumberOfLayers + 1) >= MaxNumLayer ) return -1;
    m_pLayer[m_pAvailableSlot] = new Layer;
    if (!m_pLayer[m_pAvailableSlot]) return -1;
    if (!m_pBottomLayer) m_pBottomLayer = m_pLayer[m_pAvailableSlot];

    m_pLayer[m_pAvailableSlot]->Image = img;
    m_pLayer[m_pAvailableSlot]->SrcImage = img;
    m_pLayer[m_pAvailableSlot]->Position.x = x;
    m_pLayer[m_pAvailableSlot]->Position.y = y;
    m_pLayer[m_pAvailableSlot]->Transparency = level;
    m_pLayer[m_pAvailableSlot]->Index = m_pAvailableSlot;
    m_pLayer[m_pAvailableSlot]->pPrevLayer = m_pTopLayer;
    m_pLayer[m_pAvailableSlot]->pNextLayer = 0;
    m_pLayer[m_pAvailableSlot]->Visible = true;
    m_pLayer[m_pAvailableSlot]->StretchInfo.Width = img.width;
    m_pLayer[m_pAvailableSlot]->StretchInfo.Height = img.height;
    m_pLayer[m_pAvailableSlot]->StretchInfo.OffsetX = 0;
    m_pLayer[m_pAvailableSlot]->StretchInfo.OffsetY = 0;
    m_pLayer[m_pAvailableSlot]->bZoom = false;
    m_pLayer[m_pAvailableSlot]->bTransform = false;
    m_pLayer[m_pAvailableSlot]->uRenderMethod = 0;

    if (m_pTopLayer) m_pTopLayer->pNextLayer = m_pLayer[m_pAvailableSlot];

    m_pTopLayer = m_pLayer[m_pAvailableSlot];
    while (m_pLayer[m_pAvailableSlot] != 0) m_pAvailableSlot++;
    m_nNumberOfLayers++;

    return temp;
}

int LayerManager::RemoveLayerByIndex(int index)
{
    if (!m_pLayer[index]) return -1;

    if (m_pLayer[index] == m_pBottomLayer) {
        if (m_pTopLayer == m_pBottomLayer) {
            m_pBottomLayer = 0;
            m_pTopLayer = 0;
        }
        else {
            m_pLayer[index]->pNextLayer->pPrevLayer = 0;
            m_pBottomLayer = m_pLayer[index]->pNextLayer;
        }
    }
    else if (m_pLayer[index] == m_pTopLayer) {
        if (m_pTopLayer == m_pBottomLayer) {
            m_pTopLayer = 0;
            m_pBottomLayer = 0;
        }
        else {
            m_pTopLayer = m_pLayer[index]->pPrevLayer;
            m_pLayer[index]->pPrevLayer->pNextLayer = 0;
        }
    }
    else {
        m_pLayer[index]->pPrevLayer->pNextLayer = m_pLayer[index]->pNextLayer;
        m_pLayer[index]->pNextLayer->pPrevLayer = m_pLayer[index]->pPrevLayer;
    }

    LayerRestore(index);
    if (m_pLayerFlag[index]) {
        if (m_pLayer[index]->SrcImage.address)
            free((void*)m_pLayer[index]->SrcImage.address);
        m_pLayerFlag[index] = 0;
    }

    delete m_pLayer[index];
    m_pLayer[index] = 0;

    if (m_pAvailableSlot > index)
        m_pAvailableSlot = index;

    m_nNumberOfLayers--;

    return index;
}

int LayerManager::LayerBringForward(int index)
{
    Layer * temp;
    if (!m_pLayer[index]) return -1;

    if (m_pTopLayer == m_pBottomLayer) {
        return index;
    }

    if (m_pLayer[index] == m_pTopLayer) {
        return index;
    }

    temp = m_pLayer[index]->pNextLayer;

    if (temp->pNextLayer)
        temp->pNextLayer->pPrevLayer = m_pLayer[index];
    if (m_pLayer[index]->pPrevLayer)
        m_pLayer[index]->pPrevLayer->pNextLayer = temp;

    m_pLayer[index]->pNextLayer = temp->pNextLayer;
    temp->pNextLayer = m_pLayer[index];
    temp->pPrevLayer = m_pLayer[index]->pPrevLayer;
    m_pLayer[index]->pPrevLayer = temp;

    if (m_pBottomLayer == m_pLayer[index]) m_pBottomLayer = temp;
    if (m_pTopLayer == temp) m_pTopLayer = m_pLayer[index];

    return index;
}

int LayerManager::LayerSendBackward(int index)
{
    Layer * temp;
    if (!m_pLayer[index]) return -1;

    if (m_pTopLayer == m_pBottomLayer) {
        return index;
    }

    if (m_pLayer[index] == m_pBottomLayer) {
        return index;
    }

    temp = m_pLayer[index]->pPrevLayer;

    if (temp->pPrevLayer)
        temp->pPrevLayer->pNextLayer = m_pLayer[index];
    if (m_pLayer[index]->pNextLayer )
        m_pLayer[index]->pNextLayer->pPrevLayer = temp;

    m_pLayer[index]->pPrevLayer = temp->pPrevLayer;
    temp->pPrevLayer = m_pLayer[index];
    temp->pNextLayer = m_pLayer[index]->pNextLayer;
    m_pLayer[index]->pNextLayer = temp;

    if (m_pTopLayer == m_pLayer[index]) m_pTopLayer = temp;
    if (m_pBottomLayer == temp) m_pBottomLayer = m_pLayer[index];

    return index;
}

int LayerManager::LayerBringToFront(int index)
{

    if (!m_pLayer[index]) return -1;
    if (m_pTopLayer == m_pBottomLayer) {
        return index;
    }
    if (m_pLayer[index] == m_pTopLayer) {
        return index;
    }

    if (m_pBottomLayer == m_pLayer[index])
        m_pBottomLayer = m_pLayer[index]->pNextLayer;

    m_pTopLayer->pNextLayer = m_pLayer[index];
    m_pLayer[index]->pNextLayer->pPrevLayer =  m_pLayer[index]->pPrevLayer;

    if (m_pLayer[index]->pPrevLayer)
        m_pLayer[index]->pPrevLayer->pNextLayer = m_pLayer[index]->pNextLayer;

    m_pLayer[index]->pNextLayer = 0;
    m_pLayer[index]->pPrevLayer = m_pTopLayer;
    m_pTopLayer = m_pLayer[index];

    return index;
}

int LayerManager::LayerSendToBack(int index)
{
    if (!m_pLayer[index]) return -1;
    if (m_pTopLayer == m_pBottomLayer) {
        return index;
    }
    if (m_pLayer[index] == m_pBottomLayer) {
        return index;
    }

    if (m_pTopLayer == m_pLayer[index])
        m_pTopLayer = m_pLayer[index]->pPrevLayer;

    m_pBottomLayer->pPrevLayer = m_pLayer[index];
    m_pLayer[index]->pPrevLayer->pNextLayer =  m_pLayer[index]->pNextLayer;

    if (m_pLayer[index]->pNextLayer)
        m_pLayer[index]->pNextLayer->pPrevLayer = m_pLayer[index]->pPrevLayer;

    m_pLayer[index]->pPrevLayer = 0;
    m_pLayer[index]->pNextLayer = m_pBottomLayer;
    m_pBottomLayer = m_pLayer[index];

    return index;
}

void LayerManager::RenderStretchedLayer(BitmapBufInfo & SrcImage,
                                BitmapBufInfo & DstImage,
                                RENDERSTRUCTEX & Renderstruct)
{

    int srcWidth, srcHeight, dstWidth, dstHeight;
    int srcPitch, dstPitch;
    Pixel *src, *dst, color;
    unsigned char *srcA, srcOpacity;

    if ((Renderstruct.Width<2)
        || (Renderstruct.Height<2)
        || (Renderstruct.StretchWidth<2)
        || (Renderstruct.StretchHeight<2))
        return;

    switch (SrcImage.pixelFormat & 3) {
        case 0:
            dst = (Pixel*)DstImage.address;
            dstWidth = Renderstruct.StretchWidth;
            dstHeight = Renderstruct.StretchHeight;
            dstPitch = DstImage.pitch;
            color.a = 0xFF;
            color.r = SrcImage.pixelFormat>>24;
            color.g = (SrcImage.pixelFormat>>16)&0xFF;
            color.b = (SrcImage.pixelFormat>>8)&0xFF;
            srcOpacity = Renderstruct.AlphaValue;

            SetColorARGB32(
                            (Address)dst, Renderstruct.DstX, Renderstruct.DstY,
                            dstWidth, dstHeight, dstPitch,
                            *(Color*)&color, srcOpacity);
            break;
        case 1:
            srcA = (unsigned char *)SrcImage.address;
            dst = (Pixel*)DstImage.address;
            srcWidth = Renderstruct.Width;
            srcHeight = Renderstruct.Height;
            dstWidth = Renderstruct.StretchWidth;
            dstHeight = Renderstruct.StretchHeight;
            srcPitch = SrcImage.pitch;
            dstPitch = DstImage.pitch;
            color.a = 0xFF;
            color.r = SrcImage.pixelFormat>>24;
            color.g = (SrcImage.pixelFormat>>16)&0xFF;
            color.b = (SrcImage.pixelFormat>>8)&0xFF;
            srcOpacity = Renderstruct.AlphaValue;

            A8StretchBlit2ARGB32(
                            (Address)dst, Renderstruct.DstX, Renderstruct.DstY,
                            dstWidth, dstHeight, dstPitch,
                            (Address)srcA, Renderstruct.SrcX, Renderstruct.SrcY,
                            srcWidth, srcHeight, srcPitch,
                            srcOpacity, 1, *(Color*)&color);
            break;
        case 2:
            src = (Pixel*)SrcImage.address;
            dst = (Pixel*)DstImage.address;
            srcWidth = Renderstruct.Width;
            srcHeight = Renderstruct.Height;
            dstWidth = Renderstruct.StretchWidth;
            dstHeight = Renderstruct.StretchHeight;
            srcPitch = SrcImage.pitch;
            dstPitch = DstImage.pitch;
            srcOpacity = Renderstruct.AlphaValue;

            RGB24StretchBlit2RGB24(
                            (Address)dst, Renderstruct.DstX, Renderstruct.DstY,
                            dstWidth, dstHeight, dstPitch,
                            (Address)src, Renderstruct.SrcX, Renderstruct.SrcY,
                            srcWidth, srcHeight, srcPitch,
                            srcOpacity, 1);
            break;
        case 3:
            src = (Pixel*)SrcImage.address;
            dst = (Pixel*)DstImage.address;
            srcWidth = Renderstruct.Width;
            srcHeight = Renderstruct.Height;
            dstWidth = Renderstruct.StretchWidth;
            dstHeight = Renderstruct.StretchHeight;
            srcPitch = SrcImage.pitch;
            dstPitch = DstImage.pitch;
            srcOpacity = Renderstruct.AlphaValue;

            ARGB32StretchBlit2ARGB32(
                            (Address)dst, Renderstruct.DstX, Renderstruct.DstY,
                            dstWidth, dstHeight, dstPitch,
                            (Address)src, Renderstruct.SrcX, Renderstruct.SrcY,
                            srcWidth, srcHeight, srcPitch,
                            srcOpacity, 1);
            break;
        default:
            break;
    }

//
//
//    StretchBlitStruct.IntFloatX = (int)(((double)((StretchBlitStruct.width-1)<<16))
//                                / StretchBlitStruct.nStretchWidth)+1;
//    StretchBlitStruct.IntFloatY = (int)(((double)((StretchBlitStruct.height-1)<<16))
//                                / StretchBlitStruct.nStretchHeight)+1;
//
////    StretchBlitStruct.IntFloatX = (int)(((double)((StretchBlitStruct.width-1)<<16))
////                                / (StretchBlitStruct.nStretchWidth-1));
////    StretchBlitStruct.IntFloatY = (int)(((double)((StretchBlitStruct.height-1)<<16))
////                                / (StretchBlitStruct.nStretchHeight-1));
//
//    int SrcOffset = SrcImage.pitch * Renderstruct.SrcY + Renderstruct.SrcX;
//    int DstOffset = DstImage.pitch * Renderstruct.DstY + (Renderstruct.DstX<<2);
//
//    StretchBlitStruct.nSrcPitch = SrcImage.pitch;
//    StretchBlitStruct.nDstPitch = DstImage.pitch;
//    StretchBlitStruct.pDst = DstImage.address + DstOffset;
//    StretchBlitStruct.uRenderType = SrcImage.pixelFormat;
////DebugBreak();
//    switch (StretchBlitStruct.uRenderType & 3) {
//        case 1:
//            StretchBlitStruct.pSrc = SrcImage.address + SrcOffset;
//
//            if (Renderstruct.AlphaValue<=0) return;
//            else if (255 <= Renderstruct.AlphaValue) {
//            	StretchBlitStruct.uAlphaValue = 255;
//                StretchAlphaOnlyBlend888(StretchBlitStruct);
//            }
//            else {
//                StretchBlitStruct.uAlphaValue = Renderstruct.AlphaValue;
//                StretchAlphaOnlyBlend888(StretchBlitStruct);
//            }
//
//            break;
//        case 2:
//            StretchBlitStruct.pSrc = SrcImage.address + SrcOffset
//                                   + 3 * Renderstruct.SrcX;
//
//            if (Renderstruct.AlphaValue<=0) return;
//            else if (255 <= Renderstruct.AlphaValue) {
//            	StretchBlitStruct.uAlphaValue = 255;
//                StretchBlit888(StretchBlitStruct);
//            }
//            else {
//                StretchBlitStruct.uAlphaValue = Renderstruct.AlphaValue;
//                StretchBlitBlend888_PreMul(StretchBlitStruct);
//            }
//
//            break;
//        case 3:
//            StretchBlitStruct.pSrc = SrcImage.address + SrcOffset
//                                   + 3 * Renderstruct.SrcX;
//
//            if (Renderstruct.AlphaValue<=0) return;
//            else if (255 <= Renderstruct.AlphaValue) {
//            	StretchBlitStruct.uAlphaValue = 255;
//                StretchAlphaBlit888_PreMul(StretchBlitStruct);
//            }
//            else {
//                StretchBlitStruct.uAlphaValue = Renderstruct.AlphaValue;
//                StretchAlphaBlitBlend888_PreMul(StretchBlitStruct);
//            }
//
//            break;
//        default:
//            break;
//    }
}

void LayerManager::RenderLayer(BitmapBufInfo & SrcImage,
                               BitmapBufInfo & DstImage,
                               RENDERSTRUCT & Renderstruct)
{
    if ((Renderstruct.Width<1) || (Renderstruct.Height<1)) {
        return;
    }

//    DebugBreak();
    //[Spirit/Particle][PixelAlpha][BlendOption]
    int Selector, width, height, srcPitch, dstPitch;
    Pixel *src, *dst, color;
    unsigned char *srcA, srcOpacity;

    Selector = 0;

    if (Renderstruct.RenderMethod == 0) {
        switch (SrcImage.pixelFormat & 3) {
            case 0:
                dst = (Pixel*)DstImage.address;
                width = Renderstruct.Width;
                height = Renderstruct.Height;
                dstPitch = DstImage.pitch;
                color.a = 0xFF;
                color.r = SrcImage.pixelFormat>>24;
                color.g = (SrcImage.pixelFormat>>16)&0xFF;
                color.b = (SrcImage.pixelFormat>>8)&0xFF;
                srcOpacity = Renderstruct.AlphaValue;
                SetColorARGB32(
                                (Address)dst, Renderstruct.DstX, Renderstruct.DstY,
                                width, height, dstPitch,
                                *(Color*)&color, srcOpacity);
                break;
            case 1:
                srcA = (unsigned char *)SrcImage.address;
                dst = (Pixel*)DstImage.address;
                width = Renderstruct.Width;
                height = Renderstruct.Height;
                srcPitch = SrcImage.pitch;
                dstPitch = DstImage.pitch;
                color.a = 0xFF;
                color.r = SrcImage.pixelFormat>>24;
                color.g = (SrcImage.pixelFormat>>16)&0xFF;
                color.b = (SrcImage.pixelFormat>>8)&0xFF;
                srcOpacity = Renderstruct.AlphaValue;

                A8Blit2ARGB32(
                                (Address)dst, Renderstruct.DstX,
                                Renderstruct.DstY, dstPitch,
                                (Address)srcA, Renderstruct.SrcX,
                                Renderstruct.SrcY,
                                width, height, srcPitch,
                                *(Color*)&color, srcOpacity);
                break;
            case 2:
                src = (Pixel*)SrcImage.address;
                dst = (Pixel*)DstImage.address;
                width = Renderstruct.Width;
                height = Renderstruct.Height;
                srcPitch = SrcImage.pitch;
                dstPitch = DstImage.pitch;
                srcOpacity = Renderstruct.AlphaValue;

                RGB24Blit2RGB24(
                                (Address)dst, Renderstruct.DstX,
                                Renderstruct.DstY, dstPitch,
                                (Address)src, Renderstruct.SrcX,
                                Renderstruct.SrcY,
                                width, height, srcPitch, srcOpacity);
                break;
            case 3:
                src = (Pixel*)SrcImage.address;
                dst = (Pixel*)DstImage.address;
                width = Renderstruct.Width;
                height = Renderstruct.Height;
                srcPitch = SrcImage.pitch;
                dstPitch = DstImage.pitch;
                srcOpacity = Renderstruct.AlphaValue;

                ARGB32Blit2ARGB32(
                                (Address)dst, Renderstruct.DstX,
                                Renderstruct.DstY, dstPitch,
                                (Address)src, Renderstruct.SrcX,
                                Renderstruct.SrcY,
                                width, height, srcPitch, srcOpacity);
                break;
            default:
                break;
        }
    }
//    else if (Renderstruct.RenderMethod == 1) {
//        SrcOffset = SrcImage.pitch * Renderstruct.SrcY + (Renderstruct.SrcX<<2);
//        DstOffset = DstImage.pitch * Renderstruct.DstY + (Renderstruct.DstX<<2);
//        AlphaBlitStruct.pSrc = SrcImage.address + SrcOffset;
//        AlphaBlitStruct.pDst = DstImage.address + DstOffset;
//        AlphaBlitStruct.width = Renderstruct.Width;
//        AlphaBlitStruct.height = Renderstruct.Height;
//        AlphaBlitStruct.nSrcPitch = SrcImage.pitch;
//        AlphaBlitStruct.nDstPitch = DstImage.pitch;
//        AlphaBlitStruct.uRenderType = SrcImage.pixelFormat;
//        Selector |= 8;
//    }

}

//void LayerManager::RenderToBuffer(BitmapBufInfo & img)
//{
//    RENDERSTRUCT Renderstruct;
//    _RENDERSTRUCT _Renderstruct;
//    BitmapBufInfo    Src;
//    BitmapBufInfo    Dst;
//    int DstWidth, DstHeight, SrcOffsetX, SrcOffsetY;
//    unsigned int IntFloatX, IntFloatY;
//
//    //DebugBreak();
//    Layer * TempPTR = m_pBottomLayer;
//
//
//    if (!m_bTransparent) {
//        _Renderstruct.pDst = img.address;
//        _Renderstruct.nDstPitch = img.pitch;
//        _Renderstruct.width = img.width;
//        _Renderstruct.height = img.height;
//        _Renderstruct.uRenderType = m_nBackgroundColor<<8;
//        SetColor888(_Renderstruct);
//    }
//
//    while (TempPTR) {
//        if ((!(TempPTR->Visible))
//            || ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX)
//                >= (m_stViewRectPosition.x + img.width))
//            || ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
//                >= (m_stViewRectPosition.y + img.height))
//            || ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX
//                + TempPTR->StretchInfo.Width) < m_stViewRectPosition.x)
//            || ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY
//                + TempPTR->StretchInfo.Height) < m_stViewRectPosition.y))
//            TempPTR = TempPTR->pNextLayer;
//        else {
//            if (TempPTR->bZoom) {
//                Dst.address = m_stTempBuffer.address;
//                Dst.pitch = m_stTempBuffer.pitch;
//                Src.address = TempPTR->Image.address;
//                Src.pitch = TempPTR->Image.pitch;
//                Src.pixelFormat = TempPTR->Image.pixelFormat;
//
//                Renderstruct.SrcX = 0;
//                Renderstruct.SrcY = 0;
//                Renderstruct.RenderMethod = TempPTR->uRenderMethod;
//
//                if ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX)
//                        >= m_stViewRectPosition.x) {
//                    DstWidth = (img.width + m_stViewRectPosition.x
//                               - (TempPTR->Position.x
//                               - TempPTR->StretchInfo.OffsetX))
//                               < TempPTR->StretchInfo.Width
//                             ? (img.width + m_stViewRectPosition.x
//                               - (TempPTR->Position.x
//                               - TempPTR->StretchInfo.OffsetX))
//                             : TempPTR->StretchInfo.Width;
//
//                    Src.width = TempPTR->Image.width * DstWidth
//                                 / TempPTR->StretchInfo.Width;
//                    Dst.width = DstWidth;
//                    SrcOffsetX = 0;
//
//                    Renderstruct.DstX = (TempPTR->Position.x
//                                        - TempPTR->StretchInfo.OffsetX)
//                                        - m_stViewRectPosition.x;
//
//                    if ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
//                            >= m_stViewRectPosition.y) {
//                        DstHeight = (img.height + m_stViewRectPosition.y
//                                    - (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                    < TempPTR->StretchInfo.Height
//                                  ? (img.height + m_stViewRectPosition.y
//                                    - (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                  : TempPTR->StretchInfo.Height;
//
//                        Src.height = TempPTR->Image.height * DstHeight
//                                      / TempPTR->StretchInfo.Height;
//                        Dst.height = DstHeight;
//                        SrcOffsetY = 0;
//
//                        Renderstruct.DstY = (TempPTR->Position.y
//                                            - TempPTR->StretchInfo.OffsetY)
//                                            - m_stViewRectPosition.y;
//                    }
//                    else {
//                        DstHeight = (TempPTR->StretchInfo.Height
//                                    - m_stViewRectPosition.y
//                                    + (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                    > img.height
//                                  ? img.height
//                                  : (TempPTR->StretchInfo.Height
//                                    - m_stViewRectPosition.y
//                                    + (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY));
//
//                        Src.height = TempPTR->Image.height * DstHeight
//                                      / TempPTR->StretchInfo.Height;
//                        Dst.height = DstHeight ;
//                        SrcOffsetY = TempPTR->Image.height
//                                     * (m_stViewRectPosition.y
//                                     - (TempPTR->Position.y
//                                     - TempPTR->StretchInfo.OffsetY))
//                                     / TempPTR->StretchInfo.Height;
//
//                        Renderstruct.DstY = 0;
//                    }
//
//                    if ((0 == Src.width)
//                            || (0 == Src.height)
//                            || (0 == Dst.width)
//                            || (0 == Dst.height))
//                        goto NextLayer;
//
//                    IntFloatX=(int)(((double)((Src.width-1)<<16))/(Dst.width-1));
//                    IntFloatY=(int)(((double)((Src.height-1)<<16))/(Dst.height-1));
//
//                    Dst.pixelFormat = Src.pixelFormat;
//
//                    if ((Src.pixelFormat & 3) == 1) {
//                        ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                       + (SrcOffsetX);
//                        ResizeBilinear_8u_P1(Src,Dst,IntFloatX,IntFloatY);
//                    }
//                    else {
//                        Dst.pitch = Dst.pitch<<2;
//                        ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                       + (SrcOffsetX<<2);
//                        ResizeBilinear_8u_C4A(Src,Dst,IntFloatX,IntFloatY);
//                    }
//
//                    Renderstruct.AlphaValue = TempPTR->Transparency;
//                    Renderstruct.Width = Dst.width;
//                    Renderstruct.Height = Dst.height;
//                    RenderLayer(Dst, img , Renderstruct);
//
//                }
//                else {
//                    DstWidth = (TempPTR->StretchInfo.Width
//                               - m_stViewRectPosition.x
//                               + (TempPTR->Position.x
//                               - TempPTR->StretchInfo.OffsetX))
//                               > img.width
//                             ? img.width
//                             : (TempPTR->StretchInfo.Width
//                               - m_stViewRectPosition.x
//                               + (TempPTR->Position.x
//                               - TempPTR->StretchInfo.OffsetX));
//
//                    Src.width = TempPTR->Image.width * DstWidth
//                                 / TempPTR->StretchInfo.Width;
//                    Dst.width = DstWidth;
//                    SrcOffsetX = TempPTR->Image.width
//                                 * (m_stViewRectPosition.x
//                                 - (TempPTR->Position.x
//                                 - TempPTR->StretchInfo.OffsetX))
//                                 / TempPTR->StretchInfo.Width;
//
//                    Renderstruct.DstX = 0;
//                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;
//
//                    if ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
//                            >= m_stViewRectPosition.y) {
//                        DstHeight = (img.height + m_stViewRectPosition.y
//                                    - (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                    < TempPTR->StretchInfo.Height
//                                  ? (img.height + m_stViewRectPosition.y
//                                    - (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                  : TempPTR->StretchInfo.Height;
//
//                        Src.height = TempPTR->Image.height * DstHeight
//                                      / TempPTR->StretchInfo.Height;
//                        Dst.height = DstHeight;
//                        SrcOffsetY = 0;
//
//                        Renderstruct.DstY = (TempPTR->Position.y
//                                            - TempPTR->StretchInfo.OffsetY)
//                                            - m_stViewRectPosition.y;
//                    }
//                    else {
//                        DstHeight = (TempPTR->StretchInfo.Height
//                                    - m_stViewRectPosition.y
//                                    + (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                    > img.height
//                                  ? img.height
//                                  : (TempPTR->StretchInfo.Height
//                                    - m_stViewRectPosition.y
//                                    + (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY));
//
//                        Src.height = TempPTR->Image.height * DstHeight
//                                      / TempPTR->StretchInfo.Height;
//                        Dst.height = DstHeight ;
//                        SrcOffsetY = TempPTR->Image.height
//                                     * (m_stViewRectPosition.y
//                                     - (TempPTR->Position.y
//                                     - TempPTR->StretchInfo.OffsetY))
//                                     / TempPTR->StretchInfo.Height;
//
//                        Renderstruct.DstY = 0;
//                    }
//
//                    if ((0 == Src.width)
//                            || (0 == Src.height)
//                            || (0 == Dst.width)
//                            || (0 == Dst.height))
//                         goto NextLayer;
//
//
//                    IntFloatX=(int)(((double)((Src.width-1)<<16))/(Dst.width-1));
//                    IntFloatY=(int)(((double)((Src.height-1)<<16))/(Dst.height-1));
//
//                    Dst.pixelFormat = Src.pixelFormat;
//
//                    if ((Src.pixelFormat & 3) == 1) {
//                       ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                                               + (SrcOffsetX);
//                        ResizeBilinear_8u_P1(Src,Dst,IntFloatX,IntFloatY);
//                    }
//                    else {
//                        Dst.pitch = Dst.pitch<<2;
//                       ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                                               + (SrcOffsetX<<2);
//                        ResizeBilinear_8u_C4A(Src,Dst,IntFloatX,IntFloatY);
//                    }
//                    Renderstruct.AlphaValue = TempPTR->Transparency;
//                    Renderstruct.Width = Dst.width;
//                    Renderstruct.Height = Dst.height;
//                    RenderLayer(Dst, img, Renderstruct);
//                }
//            }// End bZoom
//            else {
//                if (TempPTR->Position.x >= m_stViewRectPosition.x) {
//                    Renderstruct.Width = (TempPTR->Position.x
//                                         + TempPTR->Image.width)
//                                         < (m_stViewRectPosition.x
//                                         + img.width)
//                                       ? TempPTR->Image.width
//                                       : (m_stViewRectPosition.x
//                                         + img.width
//                                         - TempPTR->Position.x);
//
//                    Renderstruct.SrcX = 0;
//                    Renderstruct.DstX = TempPTR->Position.x
//                                        - m_stViewRectPosition.x;
//                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;
//
//                    if (TempPTR->Position.y >= m_stViewRectPosition.y) {
//                        Renderstruct.Height = (TempPTR->Position.y
//                                              + TempPTR->Image.height)
//                                              < (m_stViewRectPosition.y
//                                              + img.height)
//                                            ? TempPTR->Image.height
//                                            : (m_stViewRectPosition.y
//                                              + img.height
//                                              - TempPTR->Position.y);
//
//                        Renderstruct.SrcY = 0;
//                        Renderstruct.DstY = TempPTR->Position.y
//                                            - m_stViewRectPosition.y;
//                    }
//                    else {
//                        Renderstruct.Height = (TempPTR->Position.y
//                                              + TempPTR->Image.height)
//                                              < (m_stViewRectPosition.y
//                                              + img.height)
//                                            ? (TempPTR->Position.y
//                                              + TempPTR->Image.height
//                                              - m_stViewRectPosition.y)
//                                            : img.height;
//
//                        Renderstruct.SrcY = m_stViewRectPosition.y
//                                            - TempPTR->Position.y;
//                        Renderstruct.DstY = 0;
//                    }
//
//                    Renderstruct.AlphaValue = TempPTR->Transparency;
//                    if ((0 == Renderstruct.Width) || (0 == Renderstruct.Height))
//                        goto NextLayer;
//                    RenderLayer(TempPTR->Image,
//                               img,
//                               Renderstruct);
//                }
//                else {
//                    Renderstruct.Width = (TempPTR->Position.x
//                                         + TempPTR->Image.width)
//                                         < (m_stViewRectPosition.x
//                                         + img.width)
//                                       ? (TempPTR->Position.x
//                                         + TempPTR->Image.width
//                                         - m_stViewRectPosition.x)
//                                       : img.width;
//
//                    Renderstruct.SrcX = m_stViewRectPosition.x
//                                        - TempPTR->Position.x;
//                    Renderstruct.DstX = 0;
//                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;
//
//                    if (TempPTR->Position.y >= m_stViewRectPosition.y) {
//                        Renderstruct.Height = (TempPTR->Position.y
//                                              + TempPTR->Image.height)
//                                              < (m_stViewRectPosition.y
//                                              + img.height)
//                                            ? TempPTR->Image.height
//                                            : (m_stViewRectPosition.y
//                                              + img.height
//                                              - TempPTR->Position.y);
//
//                        Renderstruct.SrcY = 0;
//                        Renderstruct.DstY = TempPTR->Position.y
//                                            - m_stViewRectPosition.y;
//                    }
//                    else {
//                        Renderstruct.Height = (TempPTR->Position.y
//                                              + TempPTR->Image.height)
//                                              < (m_stViewRectPosition.y
//                                              + img.height)
//                                            ? (TempPTR->Position.y
//                                              + TempPTR->Image.height
//                                              - m_stViewRectPosition.y)
//                                            : img.height;
//
//                        Renderstruct.SrcY = m_stViewRectPosition.y
//                                            - TempPTR->Position.y;
//                        Renderstruct.DstY = 0;
//                    }
//                    Renderstruct.AlphaValue = TempPTR->Transparency;
//                    if ((0 == Renderstruct.Width) || (0 == Renderstruct.Height))
//                        goto NextLayer;
//                    RenderLayer(TempPTR->Image,
//                               img,
//                               Renderstruct);
//                }
//            }
//NextLayer:
//        TempPTR = TempPTR->pNextLayer;
//
//        }
//    }
//}

//
//void LayerManager::RenderToBuffer(BitmapBufInfo & img, int OffsetX, int OffsetY, int RenderLen, int RenderHt)
//{
//    RENDERSTRUCT Renderstruct;
//    _RENDERSTRUCT _Renderstruct;
//    BitmapBufInfo    Src;
//    BitmapBufInfo    Dst;
//    int DstWidth, DstHeight, SrcOffsetX, SrcOffsetY;
//    unsigned int IntFloatX, IntFloatY;
//
//    //DebugBreak();
//    Layer * TempPTR = m_pBottomLayer;
//
//
//    if (!m_bTransparent) {
//        _Renderstruct.pDst = img.address + (OffsetX<<2) + img.pitch * OffsetY;
//        _Renderstruct.nDstPitch = img.pitch;
//        _Renderstruct.width = RenderLen;
//        _Renderstruct.height = RenderHt;
//        _Renderstruct.uRenderType = m_nBackgroundColor<<8;
//        SetColor888(_Renderstruct);
//    }
//
//    while (TempPTR) {
//        if ((!(TempPTR->Visible))
//            || ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX)
//                >= (m_stViewRectPosition.x + RenderLen))
//            || ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
//                >= (m_stViewRectPosition.y + RenderHt))
//            || ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX
//                + TempPTR->StretchInfo.Width) < m_stViewRectPosition.x)
//            || ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY
//                + TempPTR->StretchInfo.Height) < m_stViewRectPosition.y))
//            TempPTR = TempPTR->pNextLayer;
//        else {
//            if (TempPTR->bZoom) {
//                Dst.address = m_stTempBuffer.address;
//                Dst.pitch = m_stTempBuffer.pitch;
//                Src.address = TempPTR->Image.address;
//                Src.pitch = TempPTR->Image.pitch;
//                Src.pixelFormat = TempPTR->Image.pixelFormat;
//
//                Renderstruct.SrcX = 0;
//                Renderstruct.SrcY = 0;
//                Renderstruct.RenderMethod = TempPTR->uRenderMethod;
//
//                if ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX)
//                        >= m_stViewRectPosition.x) {
//                    DstWidth = (RenderLen + m_stViewRectPosition.x
//                               - (TempPTR->Position.x
//                               - TempPTR->StretchInfo.OffsetX))
//                               < TempPTR->StretchInfo.Width
//                             ? (RenderLen + m_stViewRectPosition.x
//                               - (TempPTR->Position.x
//                               - TempPTR->StretchInfo.OffsetX))
//                             : TempPTR->StretchInfo.Width;
//
//                    Src.width = TempPTR->Image.width * DstWidth
//                                 / TempPTR->StretchInfo.Width;
//                    Dst.width = DstWidth;
//                    SrcOffsetX = 0;
//
//                    Renderstruct.DstX = (TempPTR->Position.x + OffsetX
//                                        - TempPTR->StretchInfo.OffsetX)
//                                        - m_stViewRectPosition.x;
//
//                    if ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
//                            >= m_stViewRectPosition.y) {
//                        DstHeight = (RenderHt + m_stViewRectPosition.y
//                                    - (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                    < TempPTR->StretchInfo.Height
//                                  ? (RenderHt + m_stViewRectPosition.y
//                                    - (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                  : TempPTR->StretchInfo.Height;
//
//                        Src.height = TempPTR->Image.height * DstHeight
//                                      / TempPTR->StretchInfo.Height;
//                        Dst.height = DstHeight;
//                        SrcOffsetY = 0;
//
//                        Renderstruct.DstY = (TempPTR->Position.y + OffsetY
//                                            - TempPTR->StretchInfo.OffsetY)
//                                            - m_stViewRectPosition.y;
//                    }
//                    else {
//                        DstHeight = (TempPTR->StretchInfo.Height
//                                    - m_stViewRectPosition.y
//                                    + (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                    > RenderHt
//                                  ? RenderHt
//                                  : (TempPTR->StretchInfo.Height
//                                    - m_stViewRectPosition.y
//                                    + (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY));
//
//                        Src.height = TempPTR->Image.height * DstHeight
//                                      / TempPTR->StretchInfo.Height;
//                        Dst.height = DstHeight ;
//                        SrcOffsetY = TempPTR->Image.height
//                                     * (m_stViewRectPosition.y
//                                     - (TempPTR->Position.y
//                                     - TempPTR->StretchInfo.OffsetY))
//                                     / TempPTR->StretchInfo.Height;
//
//                        Renderstruct.DstY = OffsetY;
//                    }
//
//                    if ((0 == Src.width)
//                            || (0 == Src.height)
//                            || (0 == Dst.width)
//                            || (0 == Dst.height))
//                        goto NextLayer;
//
//                    IntFloatX=(int)(((double)((Src.width-1)<<16))/(Dst.width-1));
//                    IntFloatY=(int)(((double)((Src.height-1)<<16))/(Dst.height-1));
//
//                    Dst.pixelFormat = Src.pixelFormat;
//
//                    if ((Src.pixelFormat & 3) == 1) {
//                        ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                       + (SrcOffsetX);
//                        ResizeBilinear_8u_P1(Src,Dst,IntFloatX,IntFloatY);
//                    }
//                    else {
//                        Dst.pitch = Dst.width<<2;
//                        ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                       + (SrcOffsetX<<2);
//                        ResizeBilinear_8u_C4A(Src,Dst,IntFloatX,IntFloatY);
//                    }
//
//                    Renderstruct.AlphaValue = TempPTR->Transparency;
//                    Renderstruct.Width = Dst.width;
//                    Renderstruct.Height = Dst.height;
//                    RenderLayer(Dst, img , Renderstruct);
//
//                }
//                else {
//                    DstWidth = (TempPTR->StretchInfo.Width
//                               - m_stViewRectPosition.x
//                               + (TempPTR->Position.x
//                               - TempPTR->StretchInfo.OffsetX))
//                               > RenderLen
//                             ? RenderLen
//                             : (TempPTR->StretchInfo.Width
//                               - m_stViewRectPosition.x
//                               + (TempPTR->Position.x
//                               - TempPTR->StretchInfo.OffsetX));
//
//                    Src.width = TempPTR->Image.width * DstWidth
//                                 / TempPTR->StretchInfo.Width;
//                    Dst.width = DstWidth;
//                    SrcOffsetX = TempPTR->Image.width
//                                 * (m_stViewRectPosition.x
//                                 - (TempPTR->Position.x
//                                 - TempPTR->StretchInfo.OffsetX))
//                                 / TempPTR->StretchInfo.Width;
//
//                    Renderstruct.DstX = OffsetX;
//                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;
//
//                    if ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
//                            >= m_stViewRectPosition.y) {
//                        DstHeight = (RenderHt + m_stViewRectPosition.y
//                                    - (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                    < TempPTR->StretchInfo.Height
//                                  ? (RenderHt + m_stViewRectPosition.y
//                                    - (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                  : TempPTR->StretchInfo.Height;
//
//                        Src.height = TempPTR->Image.height * DstHeight
//                                      / TempPTR->StretchInfo.Height;
//                        Dst.height = DstHeight;
//                        SrcOffsetY = 0;
//
//                        Renderstruct.DstY = (TempPTR->Position.y + OffsetY
//                                            - TempPTR->StretchInfo.OffsetY)
//                                            - m_stViewRectPosition.y;
//                    }
//                    else {
//                        DstHeight = (TempPTR->StretchInfo.Height
//                                    - m_stViewRectPosition.y
//                                    + (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY))
//                                    > RenderHt
//                                  ? RenderHt
//                                  : (TempPTR->StretchInfo.Height
//                                    - m_stViewRectPosition.y
//                                    + (TempPTR->Position.y
//                                    - TempPTR->StretchInfo.OffsetY));
//
//                        Src.height = TempPTR->Image.height * DstHeight
//                                      / TempPTR->StretchInfo.Height;
//                        Dst.height = DstHeight ;
//                        SrcOffsetY = TempPTR->Image.height
//                                     * (m_stViewRectPosition.y
//                                     - (TempPTR->Position.y
//                                     - TempPTR->StretchInfo.OffsetY))
//                                     / TempPTR->StretchInfo.Height;
//
//                        Renderstruct.DstY = OffsetY;
//                    }
//
//                    if ((0 == Src.width)
//                            || (0 == Src.height)
//                            || (0 == Dst.width)
//                            || (0 == Dst.height))
//                         goto NextLayer;
//
//                    IntFloatX=(int)(((double)((Src.width-1)<<16))/(Dst.width-1));
//                    IntFloatY=(int)(((double)((Src.height-1)<<16))/(Dst.height-1));
//
//                    Dst.pixelFormat = Src.pixelFormat;
//
//                    if ((Src.pixelFormat & 3) == 1) {
//                       ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                                               + (SrcOffsetX);
//                        ResizeBilinear_8u_P1(Src,Dst,IntFloatX,IntFloatY);
//                    }
//                    else {
//                        Dst.pitch = Dst.width<<2;
//                       ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                                               + (SrcOffsetX<<2);
//                        ResizeBilinear_8u_C4A(Src,Dst,IntFloatX,IntFloatY);
//                    }
//                    Renderstruct.AlphaValue = TempPTR->Transparency;
//                    Renderstruct.Width = Dst.width;
//                    Renderstruct.Height = Dst.height;
//                    RenderLayer(Dst, img, Renderstruct);
//                }
//            }// End bZoom
//            else {
//                if (TempPTR->Position.x >= m_stViewRectPosition.x) {
//                    Renderstruct.Width = (TempPTR->Position.x
//                                         + TempPTR->Image.width)
//                                         < (m_stViewRectPosition.x
//                                         + RenderLen)
//                                       ? TempPTR->Image.width
//                                       : (m_stViewRectPosition.x
//                                         + RenderLen
//                                         - TempPTR->Position.x);
//
//                    Renderstruct.SrcX = 0;
//                    Renderstruct.DstX = TempPTR->Position.x + OffsetX
//                                        - m_stViewRectPosition.x;
//                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;
//
//                    if (TempPTR->Position.y >= m_stViewRectPosition.y) {
//                        Renderstruct.Height = (TempPTR->Position.y
//                                              + TempPTR->Image.height)
//                                              < (m_stViewRectPosition.y
//                                              + RenderHt)
//                                            ? TempPTR->Image.height
//                                            : (m_stViewRectPosition.y
//                                              + RenderHt
//                                              - TempPTR->Position.y);
//
//                        Renderstruct.SrcY = 0;
//                        Renderstruct.DstY = TempPTR->Position.y + OffsetY
//                                            - m_stViewRectPosition.y;
//                    }
//                    else {
//                        Renderstruct.Height = (TempPTR->Position.y
//                                              + TempPTR->Image.height)
//                                              < (m_stViewRectPosition.y
//                                              + RenderHt)
//                                            ? (TempPTR->Position.y
//                                              + TempPTR->Image.height
//                                              - m_stViewRectPosition.y)
//                                            : RenderHt;
//
//                        Renderstruct.SrcY = m_stViewRectPosition.y
//                                            - TempPTR->Position.y;
//                        Renderstruct.DstY = OffsetY;
//                    }
//
//                    Renderstruct.AlphaValue = TempPTR->Transparency;
//                    if ((0 == Renderstruct.Width) || (0 == Renderstruct.Height))
//                        goto NextLayer;
//                    RenderLayer(TempPTR->Image,
//                               img,
//                               Renderstruct);
//                }
//                else {
//                    Renderstruct.Width = (TempPTR->Position.x
//                                         + TempPTR->Image.width)
//                                         < (m_stViewRectPosition.x
//                                         + RenderLen)
//                                       ? (TempPTR->Position.x
//                                         + TempPTR->Image.width
//                                         - m_stViewRectPosition.x)
//                                       : RenderLen;
//
//                    Renderstruct.SrcX = m_stViewRectPosition.x
//                                        - TempPTR->Position.x;
//                    Renderstruct.DstX = OffsetX;
//                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;
//
//                    if (TempPTR->Position.y >= m_stViewRectPosition.y) {
//                        Renderstruct.Height = (TempPTR->Position.y
//                                              + TempPTR->Image.height)
//                                              < (m_stViewRectPosition.y
//                                              + RenderHt)
//                                            ? TempPTR->Image.height
//                                            : (m_stViewRectPosition.y
//                                              + RenderHt
//                                              - TempPTR->Position.y);
//
//                        Renderstruct.SrcY = 0;
//                        Renderstruct.DstY = TempPTR->Position.y + OffsetY
//                                            - m_stViewRectPosition.y;
//                    }
//                    else {
//                        Renderstruct.Height = (TempPTR->Position.y
//                                              + TempPTR->Image.height)
//                                              < (m_stViewRectPosition.y
//                                              + RenderHt)
//                                            ? (TempPTR->Position.y
//                                              + TempPTR->Image.height
//                                              - m_stViewRectPosition.y)
//                                            : RenderHt;
//
//                        Renderstruct.SrcY = m_stViewRectPosition.y
//                                            - TempPTR->Position.y;
//                        Renderstruct.DstY = OffsetY;
//                    }
//                    Renderstruct.AlphaValue = TempPTR->Transparency;
//                    if ((0 == Renderstruct.Width) || (0 == Renderstruct.Height))
//                        goto NextLayer;
//                    RenderLayer(TempPTR->Image,
//                               img,
//                               Renderstruct);
//                }
//            }
//NextLayer:
//        TempPTR = TempPTR->pNextLayer;
//
//        }
//    }
//}


int LayerManager::LayerResize(int index, int width, int height)
{
    if (!m_pLayer[index]) return -1;
    if ((width < 2) || (height < 2))
        return -1;

    unsigned char * temp = 0;

    switch (GetLayerType(index)) {
        case 3 : {
            temp = (unsigned char*)calloc(width * height , 4);

            if (!temp) return -1;

            LayerRestore(index);

            m_pLayer[index]->Image.address = (Address)temp;
            m_pLayer[index]->Image.width  = width;
            m_pLayer[index]->Image.height = height;
            m_pLayer[index]->Image.pitch  = width * 4;

            ARGB32StretchBlit2ARGB32(
                            (Address)m_pLayer[index]->Image.address,
                            0, 0,
                            m_pLayer[index]->Image.width,
                            m_pLayer[index]->Image.height,
                            m_pLayer[index]->Image.pitch,
                            (Address)m_pLayer[index]->SrcImage.address,
                            0, 0,
                            m_pLayer[index]->SrcImage.width,
                            m_pLayer[index]->SrcImage.height,
                            m_pLayer[index]->SrcImage.pitch,
                            0xFF, 1);
            break;
        }
        case 1 : {
            return -1;
//            temp = (unsigned char*)calloc(width * height , 1);
//            if (!temp) return -1;
//
//            LayerRestore(index);
//
//            m_pLayer[index]->Image.address = temp;
//            m_pLayer[index]->Image.width  = width;
//            m_pLayer[index]->Image.height = height;
//            m_pLayer[index]->Image.pitch = width;
//
//            int IntFloatX=(int)(((double)((m_pLayer[index]->SrcImage.width-1)<<16)/width-1));
//            int IntFloatY=(int)(((double)((m_pLayer[index]->SrcImage.height-1)<<16)/height-1));
//
//            ResizeBilinear_8u_P1(m_pLayer[index]->SrcImage,
//                                     m_pLayer[index]->Image,
//                                     IntFloatX,
//                                     IntFloatY);
            break;
        }
        case 2 : {
            temp = (unsigned char*)calloc(width * height , 4);

            if (!temp) return -1;

            LayerRestore(index);

            m_pLayer[index]->Image.address = (Address)temp;
            m_pLayer[index]->Image.width  = width;
            m_pLayer[index]->Image.height = height;
            m_pLayer[index]->Image.pitch  = width * 4;

            ARGB32StretchBlit2RGB24(
                            (Address)m_pLayer[index]->Image.address,
                            0, 0,
                            m_pLayer[index]->Image.width,
                            m_pLayer[index]->Image.height,
                            m_pLayer[index]->Image.pitch,
                            (Address)m_pLayer[index]->SrcImage.address,
                            0, 0,
                            m_pLayer[index]->SrcImage.width,
                            m_pLayer[index]->SrcImage.height,
                            m_pLayer[index]->SrcImage.pitch,
                            0xFF, 1);
            break;
        }
        case 0 : {
            break;
        }
    }

    m_pLayer[index]->StretchInfo.Width  = width;
    m_pLayer[index]->StretchInfo.Height = height;
    m_pLayer[index]->StretchInfo.OffsetX = 0;
    m_pLayer[index]->StretchInfo.OffsetY = 0;
    m_pLayer[index]->bZoom = false;
    m_pLayer[index]->bTransform = true;

    return 0;
}

void LayerManager::LayerRestore(int index)
{
    if (!m_pLayer[index]) return;
    if (m_pLayer[index]->bTransform) {
        if (m_pLayer[index]->Image.address) {
            delete ((unsigned char*)m_pLayer[index]->Image.address);
        }
    }
    m_pLayer[index]->Image = m_pLayer[index]->SrcImage;
    m_pLayer[index]->StretchInfo.Width  = m_pLayer[index]->SrcImage.width;
    m_pLayer[index]->StretchInfo.Height = m_pLayer[index]->SrcImage.height;
    m_pLayer[index]->StretchInfo.OffsetX = 0;
    m_pLayer[index]->StretchInfo.OffsetY = 0;
    m_pLayer[index]->bZoom = false;
    m_pLayer[index]->bTransform = false;
}

int LayerManager::WarpLayerLR(int index, int StretchX, int StretchYL, int StretchYR)
{
    if (GetLayerType(index) != 3)
        return -1;


    StretchX += m_pLayer[index]->SrcImage.width;
    StretchYL += m_pLayer[index]->SrcImage.height;
    StretchYR += m_pLayer[index]->SrcImage.height;


    unsigned char * temp = 0;
    if (((StretchX>>1)>m_pLayer[index]->SrcImage.width) ||
        ((StretchYL>>1)>m_pLayer[index]->SrcImage.height) ||
        ((StretchYR>>1)>m_pLayer[index]->SrcImage.height))
        return -1;


    if (!m_pLayer[index]->bTransform) {
        int width = m_pLayer[index]->SrcImage.width<<1;
        int height = m_pLayer[index]->SrcImage.height<<1;
        width  = width > 300 ? 300 : width;
        height = height > 400 ? 400 : height;
        temp = (unsigned char *)calloc(width * height, 4);
        m_pLayer[index]->Image.address = (Address)temp;
        m_pLayer[index]->Image.pitch = width * 4;
        m_pLayer[index]->bTransform = true;
    }

    m_pLayer[index]->Image.width  = StretchX;
    m_pLayer[index]->Image.height = (StretchYL > StretchYR ? StretchYL : StretchYR) - 1;
    m_pLayer[index]->StretchInfo.Width = m_pLayer[index]->Image.width;
    m_pLayer[index]->StretchInfo.Height = m_pLayer[index]->Image.height;

    if (0 == StretchX)
        return 0;
//    WarpPerspective_8u_C4A(m_pLayer[index]->SrcImage, m_pLayer[index]->Image, StretchX, StretchYL, StretchYR);

    m_pLayer[index]->bZoom = false;
    m_pLayer[index]->bTransform = true;

    return 0;
}

int LayerManager::WarpLayerTD(int index, int StretchY, int StretchXT, int StretchXD)
{
    if (GetLayerType(index) != ARGB32)
        return -1;

    StretchY += m_pLayer[index]->SrcImage.height;
    StretchXT += m_pLayer[index]->SrcImage.width;
    StretchXD += m_pLayer[index]->SrcImage.width;

    unsigned char * temp = 0;
    if (((StretchY>>1)>m_pLayer[index]->SrcImage.height) ||
        ((StretchXT>>1)>m_pLayer[index]->SrcImage.width) ||
        ((StretchXD>>1)>m_pLayer[index]->SrcImage.width))
        return -1;

    if (!m_pLayer[index]->bTransform) {
        int width = m_pLayer[index]->SrcImage.width<<1;
        int height = m_pLayer[index]->SrcImage.height<<1;
        width  = width > 300 ? 300 : width;
        height = height > 400 ? 400 : height;
        temp = (unsigned char *)calloc(width * height, 4);
        m_pLayer[index]->Image.address = (Address)temp;
        m_pLayer[index]->Image.pitch = width * 4;
        m_pLayer[index]->bTransform = true;
    }

    m_pLayer[index]->Image.height  = StretchY;
    m_pLayer[index]->Image.width = (StretchXT > StretchXD ? StretchXT : StretchXD) -1;
    m_pLayer[index]->StretchInfo.Width = m_pLayer[index]->Image.width;
    m_pLayer[index]->StretchInfo.Height = m_pLayer[index]->Image.height;

//    printf("y=%d\n",StretchY);
    if (0 == StretchY)
        return 0;
//    WarpPerspectiveH_8u_C4A(m_pLayer[index]->SrcImage, m_pLayer[index]->Image, StretchXT, StretchXD, StretchY);

    m_pLayer[index]->bZoom = false;
    m_pLayer[index]->bTransform = true;

    return 0;
}


int LayerManager::ShearLayer(int index, int offset, int StretchX, int StretchY)
{
    unsigned char * temp = 0;

    if (!m_pLayer[index] || (abs(offset) > (m_pLayer[index]->SrcImage.width)))
        return -1;

    StretchY += m_pLayer[index]->SrcImage.height;
    StretchX += m_pLayer[index]->SrcImage.width;


    if ((GetLayerType(index) != 3) || (0 == StretchY) || (0 == StretchX))
        return -1;

    if (!m_pLayer[index]->bTransform) {
        int width = m_pLayer[index]->SrcImage.width<<1;
        int height = m_pLayer[index]->SrcImage.height<<1;
        width  = width > 400 ? 400 : width;
        height = height > 400 ? 400 : height;
        temp = (unsigned char *)calloc(width * height, 4);
        m_pLayer[index]->Image.address = (Address)temp;
        m_pLayer[index]->Image.pitch = width * 4;
        m_pLayer[index]->bTransform = true;
    }

    m_pLayer[index]->Image.height = StretchY;
    m_pLayer[index]->Image.width = StretchX;
    m_pLayer[index]->StretchInfo.Width = m_pLayer[index]->Image.width;
    m_pLayer[index]->StretchInfo.Height = m_pLayer[index]->Image.height;

//    ShearBilinear_8u_C4A(m_pLayer[index]->SrcImage, m_pLayer[index]->Image, offset);

    m_pLayer[index]->bZoom = false;
    m_pLayer[index]->bTransform = true;

    return 0;
}

int LayerManager::WaveLayer(int index, int* aSampleX16, int width, int height, int InnerWidth)
{
    unsigned char * temp = 0;

    if (!m_pLayer[index])
        return -1;

    if ((0 >= width) || (0 >= height))
        return -1;

    if (!m_pLayer[index]->bTransform) {

        temp = (unsigned char *)calloc(width * (height+2), 4);
        m_pLayer[index]->Image.address = (Address)temp;
        m_pLayer[index]->Image.pitch = width * 4;
        m_pLayer[index]->bTransform = true;
    }

    m_pLayer[index]->Image.width = width;
    m_pLayer[index]->Image.height = height;

//    CurveBilinear_8u_C4A(m_pLayer[index]->SrcImage, m_pLayer[index]->Image, aSampleX16, InnerWidth);

    m_pLayer[index]->bZoom = false;
    m_pLayer[index]->bTransform = true;

    return 0;
}

void LayerManager::LayerFlip(int index, int direction)
{
    return;
}

int LayerManager::MergeLayer(int SrcIndex, int DstIndex)
{
	if ((!m_pLayer[SrcIndex]) || (!m_pLayer[DstIndex]))
	    return -1;

	int width = m_pLayer[SrcIndex]->SrcImage.width;
	int height = m_pLayer[SrcIndex]->SrcImage.height;
	int nSrcPitch =  m_pLayer[SrcIndex]->SrcImage.pitch;
	int nDstPitch =  m_pLayer[DstIndex]->SrcImage.pitch;
	Pixel* pSrc = (Pixel*)m_pLayer[SrcIndex]->SrcImage.address;
	Pixel* pDst = (Pixel*)m_pLayer[DstIndex]->SrcImage.address;

	if ((GetLayerType(SrcIndex) == ARGB32) &&
	    (GetLayerType(DstIndex) == ARGB32) &&
	    (width <= m_pLayer[DstIndex]->SrcImage.width) &&
	    (height <= m_pLayer[DstIndex]->SrcImage.height)) {
    	LayerRestore(SrcIndex);
    	LayerRestore(DstIndex);
        for (int y=0; y<height; y++) {
            for (int x=0; x<width; x++) {
                int A = pSrc[x].a + pDst[x].a - pSrc[x].a*pDst[x].a/255;
                if (A!=0) {
                    pDst[x].r = (pSrc[x].r*pSrc[x].a + pDst[x].r*pDst[x].a
                              - pDst[x].r*pSrc[x].a*pDst[x].a/255)/A;
                    pDst[x].g = (pSrc[x].g*pSrc[x].a + pDst[x].g*pDst[x].a
                              - pDst[x].g*pSrc[x].a*pDst[x].a/255)/A;
                    pDst[x].b = (pSrc[x].b*pSrc[x].a + pDst[x].b*pDst[x].a
                              - pDst[x].b*pSrc[x].a*pDst[x].a/255)/A;
                }
                pDst[x].a = (unsigned char)A;
            }
            ((char*&)pSrc)+=nSrcPitch;
            ((char*&)pDst)+=nDstPitch;
        }
	}
	RemoveLayerByIndex(SrcIndex);
    return 0;
}

int LayerManager::LayerRotate90(int index, int times)
{
    Pixel * tempbuffer = 0;

    if (!m_pLayer[index]) return -1;

    int x,y;
    int width = m_pLayer[index]->SrcImage.width;
    int height = m_pLayer[index]->SrcImage.height;
    Pixel * src = (Pixel*)m_pLayer[index]->SrcImage.address;

    LayerRestore(index);

    times = times % 4;
    if (!times) return 0;

    switch (GetLayerType(index)) {
        case RGB24 :
        case ARGB32 : {
            tempbuffer = (Pixel*)calloc(width * height , 4);
            if (!tempbuffer)
                return -1;

            //not used for real-time, cache optimization ignored.
            //
            switch (times) {
                case 1 : {
                    for (y = 0; y < height; y++) {
                        for (x = 0; x < width; x++) {
                            tempbuffer[x * height + y] =
                                src[(height - 1 - y) * width + x];
                        }
                    }
                    m_pLayer[index]->SrcImage.pitch = height<<2;
                    m_pLayer[index]->SrcImage.width = height;
                    m_pLayer[index]->SrcImage.height = width;
                    break;
                }
                case 2 : {
                    for (y = 0; y < height; y++) {
                        for (x = 0; x < width; x++) {
                            tempbuffer[x + y * width] =
                                src[(height - 1 - y) * width + width - 1 - x];
                        }
                    }
                    break;
                }
                case 3 : {
                    for (y = 0; y < height; y++) {
                        for (x = 0; x < width; x++) {
                            tempbuffer[(width - 1 - x) * height + y] =
                                src[y * width + x];
                        }
                    }
                    m_pLayer[index]->SrcImage.pitch = height<<2;
                    m_pLayer[index]->SrcImage.width = height;
                    m_pLayer[index]->SrcImage.height = width;
                    break;
                }
            }
            memcpy(src, tempbuffer, width * height * 4);
            break;
        }
//        case A8 : {
//            tempbuffera = (byte*)calloc(width * height , 1);
//            if (!tempbuffera)
//                return E_OUT_OF_MEMORY;
//
//            //not used for real-time, cache optimization ignored.
//            //
//            switch (times) {
//                case 1 : {
//                    for (y = 0; y < height; y++) {
//                        for (x = 0; x < width; x++) {
//                            tempbuffera[x * height + y] =
//                                srca[(height - 1 - y) * width + x];
//                        }
//                    }
//                    m_pLayer[index]->SrcImage.naPitch = height;
//                    m_pLayer[index]->SrcImage.width = height;
//                    m_pLayer[index]->SrcImage.height = width;
//                    break;
//                }
//                case 2 : {
//                    for (y = 0; y < height; y++) {
//                        for (x = 0; x < width; x++) {
//                            tempbuffera[x + y * width] =
//                                srca[(height - 1 - y) * width + width - 1 - x];
//                        }
//                    }
//                    break;
//                }
//                case 3 : {
//                    for (y = 0; y < height; y++) {
//                        for (x = 0; x < width; x++) {
//                            tempbuffera[(width - 1 - x) * height + y] =
//                                srca[y * width + x];
//                        }
//                    }
//                    m_pLayer[index]->SrcImage.naPitch = height;
//                    m_pLayer[index]->SrcImage.width = height;
//                    m_pLayer[index]->SrcImage.height = width;
//                    break;
//                }
//            }
//            memcpy(srca, tempbuffera, width * height * 1);
//            break;
//        }
//        case RGB24 : {
//            tempbuffer = (short*)calloc(width * height , 2);
//            if (!tempbuffer)
//                return E_OUT_OF_MEMORY;
//
//            //not used for real-time, cache optimization ignored.
//            //
//            switch (times) {
//                case 1 : {
//                    for (y = 0; y < height; y++) {
//                        for (x = 0; x < width; x++) {
//                            tempbuffer[x * height + y] =
//                                src[(height - 1 - y) * width + x];
//                        }
//                    }
//                    m_pLayer[index]->SrcImage.pitch = height<<1;
//                    m_pLayer[index]->SrcImage.width = height;
//                    m_pLayer[index]->SrcImage.height = width;
//                    break;
//                }
//                case 2 : {
//                    for (y = 0; y < height; y++) {
//                        for (x = 0; x < width; x++) {
//                            tempbuffer[x + y * width] =
//                                src[(height - 1 - y) * width + width - 1 - x];
//                        }
//                    }
//                    break;
//                }
//                case 3 : {
//                    for (y = 0; y < height; y++) {
//                        for (x = 0; x < width; x++) {
//                            tempbuffer[(width - 1 - x) * height + y] =
//                                src[y * width + x];
//                        }
//                    }
//                    m_pLayer[index]->SrcImage.pitch = height<<1;
//                    m_pLayer[index]->SrcImage.width = height;
//                    m_pLayer[index]->SrcImage.height = width;
//                    break;
//                }
//            }
//            memcpy(src, tempbuffer, width * height * 2);
//            break;
//        }
//        case 0 : {
//                    m_pLayer[index]->SrcImage.width = height;
//                    m_pLayer[index]->SrcImage.height = width;
//                    break;
//        }
    }

    m_pLayer[index]->Image = m_pLayer[index]->SrcImage;
    m_pLayer[index]->StretchInfo.Width  = m_pLayer[index]->SrcImage.width;
    m_pLayer[index]->StretchInfo.Height = m_pLayer[index]->SrcImage.height;

    if (tempbuffer) delete tempbuffer;

    return 0;
}

//void WarpLayer(int index, int StretchX, int StretchYL, int StretchYR)
//{
//    if ((0 == StretchX) && (0 == StretchY)) {
//        m_pLayer[index]->bZoom = false;
//        m_pLayer[index]->StretchInfo.OffsetX = 0;
//        m_pLayer[index]->StretchInfo.OffsetY = 0;
//    }
//    m_pLayer[index]->bZoom = true;
//    m_pLayer[index]->StretchInfo.OffsetX = StretchX;
//    m_pLayer[index]->StretchInfo.OffsetY = StretchY;
//
//    m_pLayer[index]->StretchInfo.Width  = m_pLayer[index]->SrcImage.width
//                                          + (StretchX<<1);
//    m_pLayer[index]->StretchInfo.Height = m_pLayer[index]->SrcImage.height
//                                          + (StretchY<<1);
//
//    if (m_pLayer[index]->StretchInfo.Width < 2)
//        m_pLayer[index]->StretchInfo.Width = 2;
//    if (m_pLayer[index]->StretchInfo.Height < 2)
//        m_pLayer[index]->StretchInfo.Height = 2;
//}

void LayerManager::RenderToBuffer(BitmapBufInfo & img, int OffsetX, int OffsetY, int RenderLen, int RenderHt)
{
    RENDERSTRUCTEX Renderstruct;
    BitmapBufInfo    Src;
    int DstWidth, DstHeight, SrcOffsetX, SrcOffsetY;
//    unsigned int IntFloatX, IntFloatY;

    //DebugBreak();
    Layer * TempPTR = m_pBottomLayer;

    if (!m_bTransparent) {;
        Pixel *dst = (Pixel*)img.address;
        int dstPitch = img.pitch;
        int width = RenderLen > img.width ? img.width : RenderLen;
        int height = RenderHt > img.height ? img.height : RenderHt;
        Pixel color = *((Pixel*)(&m_nBackgroundColor));
        SetColorARGB32(
                (Address)dst, OffsetX, OffsetY, width, height,
                dstPitch, *(Color*)&color, 255);
    }

    while (TempPTR) {
        if ((!(TempPTR->Visible))
            || ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX)
                >= (m_stViewRectPosition.x + RenderLen))
            || ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
                >= (m_stViewRectPosition.y + RenderHt))
            || ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX
                + TempPTR->StretchInfo.Width) < m_stViewRectPosition.x)
            || ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY
                + TempPTR->StretchInfo.Height) < m_stViewRectPosition.y)) {
            TempPTR = TempPTR->pNextLayer;
        }
        else {
            if (TempPTR->bZoom) {
                Src.address = TempPTR->Image.address;
                Src.pitch = TempPTR->Image.pitch;
                Src.pixelFormat = TempPTR->Image.pixelFormat;

                Renderstruct.SrcX = 0;
                Renderstruct.SrcY = 0;
                Renderstruct.RenderMethod = TempPTR->uRenderMethod;

                if ((TempPTR->Position.x - TempPTR->StretchInfo.OffsetX)
                        >= m_stViewRectPosition.x) {
                    DstWidth = (RenderLen + m_stViewRectPosition.x
                               - (TempPTR->Position.x
                               - TempPTR->StretchInfo.OffsetX))
                               < TempPTR->StretchInfo.Width
                             ? (RenderLen + m_stViewRectPosition.x
                               - (TempPTR->Position.x
                               - TempPTR->StretchInfo.OffsetX))
                             : TempPTR->StretchInfo.Width;

                    Src.width = TempPTR->Image.width * DstWidth
                                 / TempPTR->StretchInfo.Width;
                    SrcOffsetX = 0;

                    Renderstruct.DstX = (TempPTR->Position.x + OffsetX
                                        - TempPTR->StretchInfo.OffsetX)
                                        - m_stViewRectPosition.x;

                    if ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
                            >= m_stViewRectPosition.y) {
                        DstHeight = (RenderHt + m_stViewRectPosition.y
                                    - (TempPTR->Position.y
                                    - TempPTR->StretchInfo.OffsetY))
                                    < TempPTR->StretchInfo.Height
                                  ? (RenderHt + m_stViewRectPosition.y
                                    - (TempPTR->Position.y
                                    - TempPTR->StretchInfo.OffsetY))
                                  : TempPTR->StretchInfo.Height;

                        Src.height = TempPTR->Image.height * DstHeight
                                      / TempPTR->StretchInfo.Height;
                        SrcOffsetY = 0;

                        Renderstruct.DstY = (TempPTR->Position.y + OffsetY
                                            - TempPTR->StretchInfo.OffsetY)
                                            - m_stViewRectPosition.y;
                    }
                    else {
                        DstHeight = (TempPTR->StretchInfo.Height
                                    - m_stViewRectPosition.y
                                    + (TempPTR->Position.y
                                    - TempPTR->StretchInfo.OffsetY))
                                    > RenderHt
                                  ? RenderHt
                                  : (TempPTR->StretchInfo.Height
                                    - m_stViewRectPosition.y
                                    + (TempPTR->Position.y
                                    - TempPTR->StretchInfo.OffsetY));

                        Src.height = TempPTR->Image.height * DstHeight
                                      / TempPTR->StretchInfo.Height;
                        SrcOffsetY = TempPTR->Image.height
                                     * (m_stViewRectPosition.y
                                     - (TempPTR->Position.y
                                     - TempPTR->StretchInfo.OffsetY))
                                     / TempPTR->StretchInfo.Height;

                        Renderstruct.DstY = OffsetY;
                    }

                    if ((0 == Src.width)
                            || (0 == Src.height)
                            || (0 == DstWidth)
                            || (0 == DstHeight))
                        goto NextLayer;

//                    IntFloatX=(int)(((double)((Src.width-1)<<16))/(Dst.width-1));
//                    IntFloatY=(int)(((double)((Src.height-1)<<16))/(Dst.height-1));
//
//                    Dst.pixelFormat = Src.pixelFormat;
//
//                    if ((Src.pixelFormat & 3) == 1) {
//                        ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                       + (SrcOffsetX);
//                        ResizeBilinear_8u_P1(Src,Dst,IntFloatX,IntFloatY);
//                    }
//                    else {
//                        Dst.pitch = Dst.width<<2;
//                        ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                       + (SrcOffsetX<<2);
//                        ResizeBilinear_8u_C4A(Src,Dst,IntFloatX,IntFloatY);
//                    }

                    Renderstruct.AlphaValue = TempPTR->Transparency;
                    Renderstruct.SrcX +=SrcOffsetX;
                    Renderstruct.SrcY +=SrcOffsetY;
                    Renderstruct.Width = Src.width;
                    Renderstruct.Height = Src.height;
                    Renderstruct.StretchWidth = DstWidth;
                    Renderstruct.StretchHeight = DstHeight;

                    RenderStretchedLayer(Src, img , Renderstruct);

                }
                else {
                    DstWidth = (TempPTR->StretchInfo.Width
                               - m_stViewRectPosition.x
                               + (TempPTR->Position.x
                               - TempPTR->StretchInfo.OffsetX))
                               > RenderLen
                             ? RenderLen
                             : (TempPTR->StretchInfo.Width
                               - m_stViewRectPosition.x
                               + (TempPTR->Position.x
                               - TempPTR->StretchInfo.OffsetX));

                    Src.width = TempPTR->Image.width * DstWidth
                                 / TempPTR->StretchInfo.Width;
                    SrcOffsetX = TempPTR->Image.width
                                 * (m_stViewRectPosition.x
                                 - (TempPTR->Position.x
                                 - TempPTR->StretchInfo.OffsetX))
                                 / TempPTR->StretchInfo.Width;

                    Renderstruct.DstX = OffsetX;
                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;

                    if ((TempPTR->Position.y - TempPTR->StretchInfo.OffsetY)
                            >= m_stViewRectPosition.y) {
                        DstHeight = (RenderHt + m_stViewRectPosition.y
                                    - (TempPTR->Position.y
                                    - TempPTR->StretchInfo.OffsetY))
                                    < TempPTR->StretchInfo.Height
                                  ? (RenderHt + m_stViewRectPosition.y
                                    - (TempPTR->Position.y
                                    - TempPTR->StretchInfo.OffsetY))
                                  : TempPTR->StretchInfo.Height;

                        Src.height = TempPTR->Image.height * DstHeight
                                      / TempPTR->StretchInfo.Height;
                        SrcOffsetY = 0;

                        Renderstruct.DstY = (TempPTR->Position.y + OffsetY
                                            - TempPTR->StretchInfo.OffsetY)
                                            - m_stViewRectPosition.y;
                    }
                    else {
                        DstHeight = (TempPTR->StretchInfo.Height
                                    - m_stViewRectPosition.y
                                    + (TempPTR->Position.y
                                    - TempPTR->StretchInfo.OffsetY))
                                    > RenderHt
                                  ? RenderHt
                                  : (TempPTR->StretchInfo.Height
                                    - m_stViewRectPosition.y
                                    + (TempPTR->Position.y
                                    - TempPTR->StretchInfo.OffsetY));

                        Src.height = TempPTR->Image.height * DstHeight
                                      / TempPTR->StretchInfo.Height;
                        SrcOffsetY = TempPTR->Image.height
                                     * (m_stViewRectPosition.y
                                     - (TempPTR->Position.y
                                     - TempPTR->StretchInfo.OffsetY))
                                     / TempPTR->StretchInfo.Height;

                        Renderstruct.DstY = OffsetY;
                    }

                    if ((0 == Src.width)
                            || (0 == Src.height)
                            || (0 == DstWidth)
                            || (0 == DstHeight))
                         goto NextLayer;
//
//                    IntFloatX=(int)(((double)((Src.width-1)<<16))/(Dst.width-1));
//                    IntFloatY=(int)(((double)((Src.height-1)<<16))/(Dst.height-1));
//
//                    Dst.pixelFormat = Src.pixelFormat;
//
//                    if ((Src.pixelFormat & 3) == 1) {
//                       ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                                               + (SrcOffsetX);
//                        ResizeBilinear_8u_P1(Src,Dst,IntFloatX,IntFloatY);
//                    }
//                    else {
//                        Dst.pitch = Dst.width<<2;
//                       ((char*&)Src.address) += SrcOffsetY * TempPTR->Image.pitch
//                                               + (SrcOffsetX<<2);
//                        ResizeBilinear_8u_C4A(Src,Dst,IntFloatX,IntFloatY);
//                    }

                    Renderstruct.AlphaValue = TempPTR->Transparency;
                    Renderstruct.SrcX +=SrcOffsetX;
                    Renderstruct.SrcY +=SrcOffsetY;
                    Renderstruct.Width = Src.width;
                    Renderstruct.Height = Src.height;
                    Renderstruct.StretchWidth = DstWidth;
                    Renderstruct.StretchHeight = DstHeight;

                    RenderStretchedLayer(Src, img, Renderstruct);
                }
            }// End bZoom
            else {
                if (TempPTR->Position.x >= m_stViewRectPosition.x) {
                    Renderstruct.Width = (TempPTR->Position.x
                                         + TempPTR->Image.width)
                                         < (m_stViewRectPosition.x
                                         + RenderLen)
                                       ? TempPTR->Image.width
                                       : (m_stViewRectPosition.x
                                         + RenderLen
                                         - TempPTR->Position.x);

                    Renderstruct.SrcX = 0;
                    Renderstruct.DstX = TempPTR->Position.x + OffsetX
                                        - m_stViewRectPosition.x;
                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;

                    if (TempPTR->Position.y >= m_stViewRectPosition.y) {
                        Renderstruct.Height = (TempPTR->Position.y
                                              + TempPTR->Image.height)
                                              < (m_stViewRectPosition.y
                                              + RenderHt)
                                            ? TempPTR->Image.height
                                            : (m_stViewRectPosition.y
                                              + RenderHt
                                              - TempPTR->Position.y);

                        Renderstruct.SrcY = 0;
                        Renderstruct.DstY = TempPTR->Position.y + OffsetY
                                            - m_stViewRectPosition.y;
                    }
                    else {
                        Renderstruct.Height = (TempPTR->Position.y
                                              + TempPTR->Image.height)
                                              < (m_stViewRectPosition.y
                                              + RenderHt)
                                            ? (TempPTR->Position.y
                                              + TempPTR->Image.height
                                              - m_stViewRectPosition.y)
                                            : RenderHt;

                        Renderstruct.SrcY = m_stViewRectPosition.y
                                            - TempPTR->Position.y;
                        Renderstruct.DstY = OffsetY;
                    }

                    Renderstruct.AlphaValue = TempPTR->Transparency;
                    if ((0 == Renderstruct.Width) || (0 == Renderstruct.Height))
                        goto NextLayer;
                    RenderLayer(TempPTR->Image,
                               img,
                               Renderstruct);
                }
                else {
                    Renderstruct.Width = (TempPTR->Position.x
                                         + TempPTR->Image.width)
                                         < (m_stViewRectPosition.x
                                         + RenderLen)
                                       ? (TempPTR->Position.x
                                         + TempPTR->Image.width
                                         - m_stViewRectPosition.x)
                                       : RenderLen;

                    Renderstruct.SrcX = m_stViewRectPosition.x
                                        - TempPTR->Position.x;
                    Renderstruct.DstX = OffsetX;
                    Renderstruct.RenderMethod = TempPTR->uRenderMethod;

                    if (TempPTR->Position.y >= m_stViewRectPosition.y) {
                        Renderstruct.Height = (TempPTR->Position.y
                                              + TempPTR->Image.height)
                                              < (m_stViewRectPosition.y
                                              + RenderHt)
                                            ? TempPTR->Image.height
                                            : (m_stViewRectPosition.y
                                              + RenderHt
                                              - TempPTR->Position.y);

                        Renderstruct.SrcY = 0;
                        Renderstruct.DstY = TempPTR->Position.y + OffsetY
                                            - m_stViewRectPosition.y;
                    }
                    else {
                        Renderstruct.Height = (TempPTR->Position.y
                                              + TempPTR->Image.height)
                                              < (m_stViewRectPosition.y
                                              + RenderHt)
                                            ? (TempPTR->Position.y
                                              + TempPTR->Image.height
                                              - m_stViewRectPosition.y)
                                            : RenderHt;

                        Renderstruct.SrcY = m_stViewRectPosition.y
                                            - TempPTR->Position.y;
                        Renderstruct.DstY = OffsetY;
                    }
                    Renderstruct.AlphaValue = TempPTR->Transparency;
                    if ((0 == Renderstruct.Width) || (0 == Renderstruct.Height))
                        goto NextLayer;
                    RenderLayer(TempPTR->Image,
                               img,
                               Renderstruct);
                }
            }
NextLayer:
        TempPTR = TempPTR->pNextLayer;

        }
    }
}

int LayerManager::GetAllLayerIds(int* pid)
{
    int count,i=0,index=0;
    if (m_nNumberOfLayers<=0) return 0;
    count = m_nNumberOfLayers;
    if (!pid) return 0;

    while (count > 0 && i < MaxNumLayer)
    {
        if (m_pLayer[i]) {
            pid[index] = i;
            count--;
            index++;
        }
        i++;
    }
    return m_nNumberOfLayers;
}

int LayerManager::GetNumberOfLayers()
{
    return m_nNumberOfLayers;
}
